#pragma once

#include <string>
#include <cstdio>
#include <cstring>
#include <cstdarg>
#include <ctime>
#include <sys/types.h>
#include <unistd.h>

// 日志系统，有日志等级。   有的报错无关紧要，有的很重要。所以日志是有等级的。
//
// #define DEBUG 0
// #define INFO 1
// #define WARNING 2
// #define ERROR 3
// #define FATAL 4 // 致命错误，肥肠严重
// #define UNKNOW 5
enum
{
    DEBUG = 0,
    INFO,
    WARNING,
    ERROR,
    FATAL,
    UNKNOW
};

const std::string filename = "tcpServer.log";

static std::string toLevelString(int level)
{
    switch (level)
    {
    case DEBUG:
        return "DEBUG";
    case INFO:
        return "INFO";
    case WARNING:
        return "WARNING";
    case ERROR:
        return "ERROR";
    case FATAL:
        return "FATAL";
    default:
        return "UNKNOW";
    }
}

static std::string getTime()
{
    time_t curr = time(nullptr);
    struct tm *tmp = localtime(&curr);
    char buffer[128];
    snprintf(buffer, sizeof(buffer), "%d-%d-%d %d:%d:%d",
             tmp->tm_year + 1900,
             tmp->tm_mon,
             tmp->tm_mday,
             tmp->tm_hour,
             tmp->tm_min,
             tmp->tm_sec);
    return buffer;
}

void logMessage(int level, const char *format, ...)
{
    char logLeft[1024];
    std::string level_string = toLevelString(level);
    std::string curr_time = getTime();
    snprintf(logLeft, sizeof(logLeft), "%s %s %d", level_string.c_str(), curr_time.c_str(), getpid());

    char logRight[1024];
    va_list p;
    va_start(p, format);
    vsnprintf(logRight, sizeof(logRight), format, p);

    // 守护进程化了，就不要打到显示器了
    // printf("%s%s\n", logLeft, logRight);

    // 写到文件中。
    FILE *fp = fopen(filename.c_str(), "a");
    if(nullptr == fp)
        return;
    fprintf(fp, "%s %s\n", logLeft, logRight);
    fflush(fp);
    fclose(fp);

    va_end(p);
}
